import axios from 'axios'
import qs from 'qs'                                       // npm install qs -S
import { ElMessage, ElMessageBox } from 'element-plus'    // elemetui 消息弹框
import { useStore } from 'vuex'
import { getToken } from '@/utils/auth'
import { REQUEST_TIMEOUT } from '@/config/project.base.config'
import errorCode from '@/config/errorCode.config'

const requestTable = {}
const throttleTime = 500
const pickKeys = ['baseURL', 'body', 'method', 'url']
const service = axios.create({
	baseURL: process.env.VUE_APP_BASE_API,               // 请求URL公共部分
	timeout: REQUEST_TIMEOUT,                            // 超时
})
const store = useStore()

axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
axios.defaults.headers['Accept'] = 'application/json;charset=UTF-8'

service.interceptors.request.use(config => {
	// 请求的唯一标识
	// Array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue) 累加器
	const request = Object.keys(config).reduce((p, n) => p + (pickKeys.includes(n) ? config[n] : ''), '')
	// 是否需要设置token
	const isToken = (config.headers || {}).isToken === false
	// 阻止重复请求
	if (config.method !== 'get' && requestTable[request] && Date.now() - requestTable[request] < throttleTime) {
		return Promise.reject(new Error())
	}
	requestTable[request] = Date.now()

	if (getToken() && !isToken) {
		// 请求头携带token
		config.headers['Authorization'] = 'Bearer' + getToken()
	}
	// get请求处理逻辑
	// 遍历config.params的key值，如果其value为object，遍历拼接url，否则直接拼接url
	if (config.method === 'get' || config.method === 'delete') {
		let url = config.url + (config.url.indexOf('?') === -1 ? '?' : '&')
		if (!config.params) config.params = {}
		for (const propName of Object.keys(config.params)) {
			const value = config.params[propName]
			const part = encodeURIComponent(propName) + '='
			if (value !== null && typeof(value) !== 'undefined') {
				if (typeof value === 'object') {
					for (const key of Object.keys(value)) {
						const params = propName + '[' + key + ']'
						const subPart = encodeURIComponent(params) + '='
						url += subPart + encodeURIComponent(value[key]) + '&'
					}
				} else {
					url += part + encodeURIComponent(value) + '&'
				}
			}
		}
		url = url.slice(0, -1)
		config.params = {}
		config.url = url
	} else if (
		(config.method === 'post' || config.method === 'put') &&
		config.headers['Content-Type'] &&
		config.headers['Content-Type'].indexOf('application/x-www-form-urlencoded') != -1) {
		// 非get请求，统一转为Form Data形式传参
		config.data = qs.stringify(config.data, {arrayFormat: 'indices', allowDots: true})
	} else {
		if (!config.data) config.data = {}
	}
	// 删除当前请求标识符
	setTimeout(() => {
		delete requestTable[request]
	}, throttleTime)
}, error => {
	Promise.reject(error)
})

service.interceptors.response.use(res => {
	const code = res.data.resp_code || 0
	const msg = errorCode[code] || res.data.resp_msg || errorCode['default']
	if (code !== 0) {
		console.log('error1', res)
		ElMessage({
			message: msg,
			type: 'error'
		})
		return Promise.reject(new Error(msg))
	}
	return res.data
}, error => {
	console.log('error2', error.response)
	if (error.response && error.response.status && error.response.data) {
		const code = error.response.status
		const msg = errorCode[code] || error.response.data.resp_msg || errorCode['default']
		switch (code) {
			case '401':
				ElMessageBox.confirm(
					'登录状态已过期，您可以继续留在该页面，或者重新登录',
					'系统提示',
					{
						confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
					}
				).then(() => {
					store.dispatch('user/LogOut').then(() => {
						location.href = '/index'
					})
				})
				break
			default:
				if (msg.includes('Invalid authorization code')) {
					ElMessageBox.confirm(
						'登录状态已过期，您可以继续留在该页面，或者重新登录',
						'系统提示',
						{
							confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning'
						}
					).then(() => {
						store.dispatch('user/LogOut').then(() => {
							location.href = '/index'
						})
					})
				} else {
					ElMessage({
						message: 'msg',
						type: 'error'
					})
				}
				return Promise.reject(new Error(msg))
		}

		let { message } = error

		if (message == "Network Error") {
      message = "后端接口连接异常"
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }

    if (message) {
      ElMessage({
        message: message,
        type: 'error',
        duration: 2 * 1000
      })
    }

    return Promise.reject(error)
	}
})

export default service